
Exceptions
Introduction
An exception is an abnormal condition, which occurs during the execution of a program. In simple words, it is a run-time error.
An exception provides a communication channel
between one point of code that detects and signals an error condition and
another portion of code that responds to the condition.
Typical exceptions that occur are division by zero,
opening a file that is not existing, access the array position beyond the
maximum size and so on.

In Java, exceptions
are objects, which describes the error conditions that can occur in the
program. The following block diagram shows the class
hierarchy for exception objects:
All exceptions are subclasses of the class
Throwable. There are two branches under Throwable.
One Exception, used for exceptional condition that
the user programs will come across and are to be handled. Unhandled
exceptions/conditions encountered during execution are referred to as Runtime
Exceptions an honorable term for program bug !!!
Second Error, exceptions that do not occur under
normal condition and they have to do much with Java run-time environment
itself. Stack Overflow is an example for this. Normally, your program cannot
handle such exceptions, nor it is expected to. So, throughout our study, we are
dealing with Exception class.
The main use of having exceptions is:
1.
To
overcome the abnormal program termination.
2.
To
anticipate and fix errors that your program may come across.
When a program throws an exception, the program is
terminated abnormally. This exception should be caught by an exception handler and
dealt with immediately. Suppose there are no explicitly specified handlers, a
default exception handler is called which displays a string that contains the
details of the exception being caught. Here are few examples which throws
exceptions.
class SimpleExec
{
public static void main(String args[])
{
int a=0,b=10;
float result=b/a;
System.out.println("Th result is " +result);
}
}
class ArrayNoExec
{
public static void main(String args[])
{
int arr[]=new int[4];
arr[0]=25;
arr[1]=50;
arr[2]=75;
arr[3]=100;
arr[4]=125;
for(int i=0;i<=3;i++)
{
System.out.println(arr[i]);
}
}
}
Exception handling in Java is done using five
keywords
1.
try
2.
catch
3.
throw
4.
throws
5.
finally.
All the statements, which you want to examine for
exceptions are placed within a try block. If an exception occurs within the try
block, it is thrown. The thrown exception can be caught using the catch block
and is handled in some meaningful manner. Any exception thrown by a method should
be specified by the throws clause. The user-defined exceptions can be thrown
using the throw clause. Any code that must be executed whether or not an
exception has occurred can be contained in the finally block.
try and catch Blocks
As explained in the previous section, any
anticipated exception must be thrown and caught explicitly. This is done using
the try and catch blocks.
The code sequence that has to be guarded for
exceptions should be put within the try block. The catch block should
immediately follow the try block. The catch block could contain the statements
specifying the type and causes for the exception to be thrown. This is shown in
the following example.
class TryCatchDemo
{
public static void main(String args[])
{
int a=0,b=10;
float result=0f;
try
{
result=b/a;
}
catch(ArithmeticException e)
{
System.out.println(e);
}
System.out.println("The result is " +result);
}
}
class ArrayExec
{
public static void main(String args[])
{
int arr[]=new int[4];
try
{
arr[0]=25;
arr[1]=50;
arr[2]=75;
arr[3]=100;
arr[4]=125;
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("you have made an error");
}
for(int i=0;i<=3;i++)
{
System.out.println(""+arr[i]);
}
}
}
Suppose the code sequence
you are guarding generates more than one type of exception, a single catch
block may not work. Under such circumstances you can have multiple catch blocks
with each block matching one of the exceptions. When a particular exception is
thrown from the try block, the catch statements are searched for the match.
Once found, the corresponding statements in the catch block are executed. If no
match is found, the default exception handler is invoked.
When you define a catch
block, that block will catch exceptions of the class specified, including any
exceptions that are subclasses of the one specified. In this way, you can handle categories of exceptions in a
single catch block.
For less generic (or more
specific) exception handling, you can specify one exception class in one
particular catch block and a parent class of that exception in another catch
block. This handling of the more specific exceptions those of the subclass
separately from others of the same parent class is governed by following rules
1.
A
more specific catch block must precede a more general one in the source.
Failure to meet this ordering requirement causes compiler error.
2.
Only
one catch block, that is the first applicable one, will be executed.
class MultiCatchdemo
{
public static void main(String args[])
{
int arr[];
int a=0,b=10;
float result=0f;
try
{
result=b/a;
arr=new int[-10];
}
catch(ArithmeticException e1)
{
System.out.println("Trying to divide by zero");
}
catch(NegativeArraySizeException e2)
{
System.out.println("Using negative subscripts");
}
finally
{
System.out.println("The finally block is executed whether
or not Exception is thrown");
}
}
}
finally Block
As mentioned earlier, whether or not an exception is
thrown, the statement within the finally block is executed after the execution
of statements within the try/catch block. In case an exception is thrown, the
finally block will be executed even if no catch matches it. The try block
requires either a catch block or finally block. Consider the following
examples.
class FinallyDemo
{
static int arr[];
public static void main(String args[])
{
try
{
arr=new int[3];
}
catch(NegativeArraySizeException e)
{
System.out.println("Negative subscript used");
}
finally
{
System.out.println("inside Finally");
}
}
}
The circumstances that can prevent execution of the
code in the finally block are
1.
The
death of the thread
2.
The
use of System.exit()
3.
Turning
off the power of the CPU
4.
An
exception arising in the finally block itself.
Whenever a program does not want to handle
exceptions, it must specify this behavior using throws clause so that the
callers of this method can guard against that exception. The throws clause
usually contains a list of types of exceptions that are likely to occur in that
program. The general form of a method declaration that uses a throws clause
would look like
type methodname(parameter
list) throws exception list
{
Body of the method
}
Usage of throws clause is shown in the following
example.
class ThrowsDemo
{
public static void main(String args[]) throws
ArrayIndexOutOfBoundsException
{
int arr[]=new int[4];
arr[0]=25;
arr[1]=50;
arr[2]=75;
arr[3]=100;
arr[4]=125;
for(int i=0;i<=3;i++)
{
System.out.println(arr[i]);
}
}
}
Java does allow users to create their own exceptions
so that according to the situations defined by the user an exception can be
thrown. It is also possible to set any condition or value to a variable and
generate user-defined exceptions.
All you have to do is first define this class that
explains the exception identifying its properties. This user-defined exception
(class) can be thrown accordingly using the throw clause like the one depicted
below.
class DivByZeroExcep extends
Exception
{
DivByZeroExcep(String msg)
{
super(msg);
}
}
public class DivByZeroN
{
public void division()
{
int num1 = 15;
int num2 = 0;
try {
if ( num2 == 0)
throw new DivByZeroExcep("/ by 0");
System.out.println(num1 + " /" + num2 +
" = " +
(num1 / num2));
} catch (DivByZeroExcep e) {
System.out.println("Dealt with " + e);
} finally {
System.out.println("Finally Finally");
}
System.out.println("Returning from division
method");
}
public static void main(String args[])
{
new
DivByZeroN().division();
System.out.println("Returning from main");
}
}
class MyExec extends
Exception
{
String name;
MyExec(String str)
{
name=str;
System.out.println(" in MyExec constructor");
}
public String toString()
{
System.out.println(" in MyExec toString()");
return "MyExec[" +name+ "]";
}
}
public class ThrowDemo
{
public static void main(String args[])
{
for(int i = 0; i < args.length; i++)
{
String str=args[i];
try
{
if(str.equalsIgnoreCase("excep"))
{
System.out.println( i+1 + ". " +
"Congrats!! You have generated your exception");
throw new MyExec(str);
}
else
{
System.out.println( i+1 + ". " +
"Sorry!! You have not generated any exceptions");
}
}catch(MyExec m)
{
System.out.println(" in catch
block");
System.out.println("Generated Exception
" +m);
}
} // eo for
} // eo main
} // eo ThrowDemo
|
Case |
Exception Occurs ? |
Try { } Exists ? |
Matching Catch(){ } Exists ? |
Execution Behaviour |
|
1 |
No |
|
|
Normal Flow. |
|
2 |
Yes |
No |
|
Method Terminates. |
|
3 |
Yes |
Yes |
No |
Method Terminates. |
|
4 |
Yes |
Yes |
Yes |
a)
Terminates try { } block b)
Execute body of first handler (matching/parent catch block) c)
Continue normal flow after catch block (beginning with finally block,
if any). |
·
Discussion
of exception handling and exception class hierarchy.
·
Defining
new exception types.
·
Explanation
of the try-catch-finally construct and control flow paths through the
construct.
·
The
usage of the throw / throws clause.
1)
Which
of the following must be true of the object thrown by a throw statement?
a)
It
must be assignable to the Throwable type.
b)
It
must be assignable to the Error type.
c)
It
must be assignable to the Exception type.
d)
It
must be assignable to the String type
.
2)
Which
of the following are true about the finally clause of a try-catch-finally
statement?
a)
It
is only executed after a catch clause has executed.
b)
It
is only executed if a catch clause has not executed.
c)
It
is always executed unless its thread terminated.
d)
It
is only executed if an exception is thrown.
3)
A
catch clause may catch exceptions of which type?
a)
The
Throwable type.
b)
The
Error type.
c)
The
Exception type.
d)
The
String type.
4)
It
is possible to place finally clause before the catch clause?
a)
True.
b)
False.
5)
It
is possible to place finally clause just after the try clause?
a)
True.
b)
False.
6)
Pick
from the following the incorrect statements for multiple catch clause -
a)
There
is no provision for multiple catch clause in java.
b)
The
catch clause for a subclass exception should succeed parent class exception.
c)
The
catch clause for a subclass exception should precede parent class exception.
d)
The
orderering of catch clause is immaterial.
7)
Pick
from the following the correct statements for exceptions in java -
a)
Exceptions
is an outdated technique and has been deprecated.
b)
A
well written program has a matching catch clause for all runtime exceptions.
c)
Exception
is not an error but a special condition in java programming paradigm.
d)
Exceptions
of the type Error are easily handled by a java program.
8)
The
program resumes from the point of occurrence of exception in the try block
after it has been successfully handled by a catch block?
a)
True.
b)
False.
9)
Choose
the correct ones -
a)
The
execution of an iterative construct is terminated gracefully when an exception
is encountered and handed successfully.
b)
The
execution path becomes chaotic and the system crashes if the program is unable
to handle an exception.
c)
A
program terminates gracefully after exception handling.
d)
The
execution path of a program is well defined even if the Exception context is
unable to handle an exception.
10)
What
is the result of executing the following code, using the parameters 4 and 0:
public void divide(int a,
int b) {
try {
int c = a / b;
} catch (Exception e) {
System.out.print("Exception
");
} finally {
System.out.println("Finally");
}
a)
Prints
out: Exception Finally
b)
Prints
out: Finally
c)
Prints
out: Exception
d)
No
output
Select
the most appropriate answer.
·
Write
a program that demonstrates the occurence of exception using only the try and
finally blocks.
·
Write
a program and check out the catching of
exceptions in hierarchy.